
package ija.model.basis;

import java.io.Serializable;

/**
 * Třída reprezentuje pozici na šachovnici.
 * @author Radek Necas, xnecas18
 * @see ija.model.basis.Figure, ija.model.basis.Desk
 */
public class Position implements Serializable {
    
    protected char columnChar;
    protected int rowNumber;
    protected Desk desk;
    protected Figure figure;
    
    
    /**
     * Konstruktor vytváří pozici.
     * @param d šachovnice do které pozice patří.
     * @param c identifikátor sloupce vytvářené pozice.
     * @param r identifikátor řádku vytvářené pozice.
     */
    public Position(Desk d, char c, int r) {
        desk = d;
        figure = null;
        columnChar = c;
        rowNumber = r;
    }
    
    /**
     * Metoda pro získání vzdálené pozice.
     * @param dC rozdíl sloupců.
     * @param dR rozdíl řádků.
     * @return pozice téže šachovnice, vzdáleno o uvedený počet řádků a sloupců.
     */
    public Position nextPosition(int dC, int dR) {
        return desk.getPositionAt((char)((int)columnChar+dC), rowNumber+dR);
    }
    
    /**
     * Metoda pro získání figurky.
     * @return figurku obsaženou na dané pozici. Pokud na pozici žádná není, pak null.
     */
    public Figure getFigure() {
        return figure;
    }
    
    /**
     * Vklada figurku na pozici.
     * Kopíruje se odkaz na figurku, nevytváří se nová figurka stejného obsahu.
     * V případě, že na pozici před vložením již byla jiná figurka, metoda ji nahradí novou,
     * ale nestará se o obsah staré (její odkaz na pozici).
     * 
     * @param f figurka, jenž se bude vkládat.
     * @return figurku, která byla na pozici před vložení. Pokud zde žádná nebyla, pak null.
     */
    public Figure putFigure(Figure f) {
        Figure retFigure = figure;
        //Figure retFigure = removeFigure();
        figure = f;
        f.position = this;
        /*if(retFigure != null)
            retFigure.deletePosition();*/
        return retFigure;
    }
    
    /**
     * Metoda odstraňuje figurku z pozice.
     * Pozice odstranene figurky zustava zachovana.
     * @return odkaz na odstraněnou figurku nebo null.
     */
    public Figure removeFigure() {
        Figure retFigure = this.figure;
        this.figure = null;
        /*
        if(retFigure != null)
            retFigure.deletePosition();
        */
        return retFigure;
    }    
    
    /**
     * 
     * @return příslušná deska. 
     */
    public Desk getDesk() {
        return desk;
    }
    
    /**
     * 
     * @return identifikátor sloupce. 
     */
    public char getColumnChar() {
        return columnChar;
    }
    
    /**
     * 
     * @return identifikátor řádku.
     */
    public int getRowNumber() {
        return rowNumber;
    }
    
    /**
     * Test zda je pozice na stejném řádku.
     * Pozice nemusí být součástí stejné šachovnice.
     * @param p testovaná pozice.
     * @return true při splnění testu, jinak false.
     */
    public boolean sameRow(Position p) {
        if(!desk.isInside(p))
            return false;
        
        return(p.getRowNumber() == rowNumber);
    }
    
    /**
     * Test zda je pozice na stejném sloupci.
     * Pozice nemusí být součástí stejné šachovnice.
     * @param p testovaná pozice.
     * @return true při splnění testu, jinak false.
     */
    public boolean sameColumn (Position p) {
        if(!desk.isInside(p)) 
            return false;
        
        return(p.getColumnChar() == columnChar);
    }
    
    /**
     * Test zda je pozice na stejné diagonále.
     * Pozice nemusí být součástí stejné šachovnice.
     * @param p testovaná pozice.
     * @return true při splnění testu, jinak false.
     */
    public boolean sameDiagonal(Position p) {
        if(!desk.isInside(p))
            return false;
        
        int dC = p.getColumnChar() - columnChar;
        int dR = p.getRowNumber() - rowNumber;
        
        if(dC == dR || dC == -dR)
            return true;
        
        return false;
    }
    
    /**
     * Metoda vypisuje na stdout obsah pozice.
     */
    public void print() {
        String s = "Pozice: " + this.toString() + " ::: Figurka: ";
        s += (this.getFigure() == null ? "NULL" : this.getFigure().toString());
        System.out.print(s);
    }
    
    
    @Override
    public String toString() {
        return(Character.toString(columnChar) + Integer.toString(rowNumber));
    }
    
    @Override
    public boolean equals(Object o) {
        if(o instanceof Position) {
            Position po = (Position) o;
            if((po.getRowNumber() == rowNumber) && (po.getColumnChar() == columnChar))
                return true;
        }

        return false;
    }

    @Override
    public int hashCode() {
        return (int)columnChar + rowNumber*10;
    }
}